<template>
  <div>
    <canvas ref="canvasRef" width="800" height="600"></canvas>
    <button @click="zoomIn">放大</button>
    <button @click="zoomOut">缩小</button>
    <!-- 添加定位按钮 -->
    <button @click="locate">定位</button>
    <div>
      <div v-for="(item, index) in newPoints" :key="index">
        <div ref="externalPointRef" :draggable="item.maplat === ''" @dragstart="handleDragStart($event, index)" @dragend="handleDragEnd($event,index)">{{ item.pointName }}</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import mapImage from '@/assets/images/map/map.jpg';
import point from '@/assets/images/map/point.png';
import pointBlue from '@/assets/images/map/pointBlue.png'; // 新增第二张点图片
import deleteIcon from '@/assets/images/map/deleteIcon.png'; // 新增删除图标

const canvasRef = ref<HTMLCanvasElement | null>(null);
const externalPointRef = ref<HTMLElement | null>(null);
const scale = ref(1);
const MIN_SCALE = 0.1;
const MAX_SCALE = 5;
const ZOOM_STEP = 0.05;
// 图片
const image = new Image();
image.src = mapImage;
const imagePoint = new Image();
imagePoint.src = point;
const imagePoint2 = new Image(); // 新增第二张点图片对象
imagePoint2.src = pointBlue;
const deleteImage = new Image();
deleteImage.src = deleteIcon;
// 待新增点位列表
const newPoints:any = ref([
  { id: 3, pointName: '第三个摄像头', isSelected: false, maplat: '', maplon: '' },
  { id: 4, pointName: '第四个摄像头', isSelected: false, maplat: '', maplon: '' },
  { id: 5, pointName: '第五个摄像头', isSelected: false, maplat: '', maplon: '' },
]);
// 新增变量用于记录图片的偏移量
const offsetX = ref(0);
const offsetY = ref(0);
// 记录鼠标按下时的位置
const startX = ref(0);
const startY = ref(0);
// 记录鼠标是否按下
const isDragging = ref(false);
// 记录点是否被拖动
const isPointDragging = ref(false);
// 记录当前拖动点的 id
const draggingPointId = ref<number | null>(null);
// 记录外部点是否正在拖动
const isExternalPointDragging = ref(false);

// 定义要绘制的点的数组，每个点包含 id、maplat、maplon 坐标、半径和是否选中
const points:any = ref([
  { id: 1, pointName: '第一个摄像头', maplat: 20, maplon: 30, radius: 5, isSelected: false, pointType: '1' },
  { id: 2, pointName: '第二个摄像头', maplat: 50, maplon: 80, radius: 5, isSelected: false, pointType: '1' },
  // 可以继续添加更多的点
]);

const drawImage = () => {
  const canvas = canvasRef.value;
  if (canvas) {
    const ctx = canvas.getContext('2d');
    if (ctx) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.save();
      ctx.scale(scale.value, scale.value);
      ctx.translate(offsetX.value / scale.value, offsetY.value / scale.value);
      ctx.drawImage(image, 0, 0);

     // 绘制虚线连接点
     if (points.value.length > 1) {
        ctx.beginPath();
        ctx.setLineDash([5, 5]); // 设置虚线样式
        ctx.strokeStyle = 'white';
        ctx.lineWidth = 2 / scale.value; // 根据缩放比例调整线宽

        const firstPoint = points.value[0];
        const firstX = (firstPoint.maplat as number) ;
        const firstY = (firstPoint.maplon as number) ;
        ctx.moveTo(firstX, firstY);

        for (let i = 1; i < points.value.length; i++) {
          const currentPoint = points.value[i];
          const currentX = (currentPoint.maplat as number) ;
          const currentY = (currentPoint.maplon as number) ;
          ctx.lineTo(currentX, currentY);
        }

        ctx.stroke();
      }

      // 绘制所有点
      points.value.forEach((point: any) => {
        const currentImage = point.isSelected ? imagePoint2 : imagePoint;

        // 保存当前画布状态
        ctx.save();
        // 恢复到默认缩放比例
        ctx.setTransform(1, 0, 0, 1, 0, 0);

        // 计算点在画布上的实际位置
        const actualX = (point.maplat as number) * scale.value + offsetX.value;
        const actualY = (point.maplon as number) * scale.value + offsetY.value;

        ctx.beginPath();
        // 修改图片绘制尺寸为 26x33
        ctx.drawImage(currentImage, actualX - 13, actualY - 16.5, 26, 33);
        ctx.fill();

        if (point.isSelected) {
          // 绘制选中框
          const boxWidth = 110;
          const boxHeight = 20;
          const boxX = actualX - boxWidth / 2;
          const boxY = actualY - 16.5 - boxHeight - 5;

          ctx.fillStyle = 'rgba(13, 15, 19,0.8)';
          ctx.fillRect(boxX, boxY, boxWidth, boxHeight);

          // 绘制名字
          ctx.fillStyle = 'white';
          ctx.font = '14px Arial';
          ctx.fillText(point.pointName, boxX + 5, boxY + 15);

          // 绘制删除图标
          const iconSize = 13;
          const iconX = boxX + boxWidth - iconSize - 5;
          const iconY = boxY + (boxHeight - iconSize) / 2;
          ctx.drawImage(deleteImage, iconX, iconY, 12, 13);
        }

        // 恢复之前的画布状态
        ctx.restore();
      });

      ctx.restore();
    }
  }
};

const zoomIn = () => {
  if (scale.value < MAX_SCALE) {
    scale.value += ZOOM_STEP;
    drawImage();
  }
};

const zoomOut = () => {
  if (scale.value > MIN_SCALE) {
    scale.value -= ZOOM_STEP;
    drawImage();
  }
};

const handleWheel = (event: WheelEvent) => {
  event.preventDefault();
  const canvas = canvasRef.value;
  if (canvas) {
    const rect = canvas.getBoundingClientRect();
    const mouseX = event.clientX - rect.left;
    const mouseY = event.clientY - rect.top;

    const delta = event.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;
    const newScale = scale.value + delta;
    if (newScale >= MIN_SCALE && newScale <= MAX_SCALE) {
      const oldScale = scale.value;
      scale.value = newScale;

      // 计算鼠标在缩放前后的相对位置
      const mouseXRelative = (mouseX - offsetX.value) / oldScale;
      const mouseYRelative = (mouseY - offsetY.value) / oldScale;

      // 根据相对位置调整偏移量
      offsetX.value = mouseX - mouseXRelative * scale.value;
      offsetY.value = mouseY - mouseYRelative * scale.value;

      drawImage();
    }
  }
};

// 处理鼠标按下事件
const handleMouseDown = (event: MouseEvent) => {
  const canvas = canvasRef.value;
  if (canvas) {
    const rect = canvas.getBoundingClientRect();
    const clickX = (event.clientX - rect.left - offsetX.value) / scale.value;
    const clickY = (event.clientY - rect.top - offsetY.value) / scale.value;

    let isPointClicked = false;
    points.value.forEach((point:any) => {
      const imageX = (point.maplat as number) - 13;
      const imageY = (point.maplon as number) - 16.5;
      const imageWidth = 26;
      const imageHeight = 33;

      if (
        clickX >= imageX &&
        clickX <= imageX + imageWidth &&
        clickY >= imageY &&
        clickY <= imageY + imageHeight
      ) {
        isPointDragging.value = true;
        draggingPointId.value = point.id;
        startX.value = clickX;
        startY.value = clickY;
        isPointClicked = true;
      }

      // 检查是否点击了删除图标
      if (point.isSelected) {
        const boxWidth = 100;
        const boxHeight = 20;
        const boxX = (point.maplat as number) - boxWidth / 2;
        const boxY = (point.maplon as number) - 16.5 - boxHeight - 5;
        const iconSize = 16;
        const iconX = boxX + boxWidth - iconSize - 5;
        const iconY = boxY + (boxHeight - iconSize) / 2;

        if (
          clickX >= iconX &&
          clickX <= iconX + iconSize &&
          clickY >= iconY &&
          clickY <= iconY + iconSize
        ) {
          // 删除点
          points.value = points.value.filter((p:any) => p.id !== point.id);
          const index = newPoints.value.findIndex((p:any) => p.id === point.id);
          if (index !== -1) {
            newPoints.value[index].maplat = '';
            newPoints.value[index].maplon = '';
          }
          drawImage();
        }
      }
    });

    if (!isPointClicked) {
      // 取消所有点的选中状态
      points.value.forEach((p:any) => p.isSelected = false);
      isDragging.value = true;
      startX.value = event.offsetX;
      startY.value = event.offsetY;
    }

    drawImage();
  }
};

// 处理鼠标移动事件
const handleMouseMove = (event: MouseEvent) => {
  const canvas = canvasRef.value;
  if (canvas) {
    const rect = canvas.getBoundingClientRect();
    const mouseX = (event.clientX - rect.left - offsetX.value) / scale.value;
    const mouseY = (event.clientY - rect.top - offsetY.value) / scale.value;

    let isOverPoint = false;
    points.value.forEach((point:any) => {
      const imageX = (point.maplat as number) - 13;
      const imageY = (point.maplon as number) - 16.5;
      const imageWidth = 26;
      const imageHeight = 33;

      if (
        mouseX >= imageX &&
        mouseX <= imageX + imageWidth &&
        mouseY >= imageY &&
        mouseY <= imageY + imageHeight
      ) {
        isOverPoint = true;
      }
    });

    if (isOverPoint) {
      canvas.style.cursor = 'pointer';
    } else {
      canvas.style.cursor = 'default';
    }

    if (isPointDragging.value) {
      const dx = mouseX - startX.value;
      const dy = mouseY - startY.value;

      const currentPoint = points.value.find((point:any) => point.id === draggingPointId.value);
      if (currentPoint) {
        // 计算新的点位置
        let newMaplat = (currentPoint.maplat as number) + dx;
        let newMaplon = (currentPoint.maplon as number) + dy;

        // 限制点的位置在图片范围内
        newMaplat = Math.max(13, Math.min(newMaplat, image.width - 13));
        newMaplon = Math.max(16.5, Math.min(newMaplon, image.height - 16.5));

        currentPoint.maplat = newMaplat;
        currentPoint.maplon = newMaplon;

        startX.value = mouseX;
        startY.value = mouseY;

        drawImage();
        console.log(`点 ${draggingPointId.value} 拖动到的位置相对于图片: (${newMaplat}, ${newMaplon})`);
      }
    } else if (isDragging.value) {
      const dx = event.offsetX - startX.value;
      const dy = event.offsetY - startY.value;
      offsetX.value += dx;
      offsetY.value += dy;
      startX.value = event.offsetX;
      startY.value = event.offsetY;
      drawImage();
    }
  }
};

// 处理鼠标松开事件
const handleMouseUp = () => {
  isDragging.value = false;
  isPointDragging.value = false;
  draggingPointId.value = null;
  console.log('拖动结束，当前 points 数组:', points.value);
};

// 处理点击事件
const handleClick = (event: MouseEvent) => {
  const canvas = canvasRef.value;
  if (canvas) {
    const rect = canvas.getBoundingClientRect();
    const clickX = (event.clientX - rect.left - offsetX.value) / scale.value;
    const clickY = (event.clientY - rect.top - offsetY.value) / scale.value;

    // 取消所有点的选中状态
    points.value.forEach((p:any) => p.isSelected = false);

    points.value.forEach((point:any) => {
      const imageX = (point.maplat as number) - 13;
      const imageY = (point.maplon as number) - 16.5;
      const imageWidth = 26;
      const imageHeight = 33;

      if (
        clickX >= imageX &&
        clickX <= imageX + imageWidth &&
        clickY >= imageY &&
        clickY <= imageY + imageHeight
      ) {
        console.log(`点 ${point.id} 被点击了！`);
        // 选中点
        point.isSelected = true;
        drawImage();
      }
    });
    console.log(points)
  }
};

// 处理外部点拖动开始事件
const handleDragStart = (event: DragEvent, index: number) => {
  isExternalPointDragging.value = true;
  // 设置拖动时的自定义图片
  event.dataTransfer?.setDragImage(imagePoint, 13, 16.5);
};

// 处理外部点拖动结束事件
const handleDragEnd = (event: DragEvent,index: number) => {
  const canvas = canvasRef.value;
  if (canvas) {
    const rect = canvas.getBoundingClientRect();
    if (
      event.clientX >= rect.left &&
      event.clientX <= rect.right &&
      event.clientY >= rect.top &&
      event.clientY <= rect.bottom
    ) {
      const clickX = (event.clientX - rect.left - offsetX.value) / scale.value;
      const clickY = (event.clientY - rect.top - offsetY.value) / scale.value;
      const draggedPoint = newPoints.value[index];
      const newPoint:any = {
        id: draggedPoint.id,
        pointName: draggedPoint.pointName,
        maplat: clickX,
        maplon: clickY,
        radius: 5,
        isSelected: false,
        pointType: '1'
      };
      points.value.push(newPoint);
      const newIndex = newPoints.value.findIndex((p:any) => p.id === draggedPoint.id);
      if (newIndex !== -1) {
        newPoints.value[newIndex].maplat = clickX;
        newPoints.value[newIndex].maplon = clickY;
      }
      drawImage();
      console.log(`新点 ${newPoint.id} 放置在相对于图片的位置: (${clickX}, ${clickY})`);
    }
  }
  isExternalPointDragging.value = false;
};

// 定位函数
const locate = () => {
  const canvas = canvasRef.value;
  if (canvas) {
    // 适当放大，例如放大到 2 倍
    scale.value = 2;
    // 计算图片中心点相对于画布的偏移量
    offsetX.value = (canvas.width / 2 - image.width / 2 * scale.value);
    offsetY.value = (canvas.height / 2 - image.height / 2 * scale.value);
    drawImage();
  }
};

onMounted(() => {
  const canvas = canvasRef.value;
  if (canvas) {
    canvas.addEventListener('wheel', handleWheel);
    canvas.addEventListener('mousedown', handleMouseDown);
    canvas.addEventListener('mousemove', handleMouseMove);
    canvas.addEventListener('mouseup', handleMouseUp);
    canvas.addEventListener('click', handleClick);

    image.onload = () => {
      drawImage();
    };
  }
});
</script>